package com.google.code.androiddatasender;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;

public class Msg {
    public Packet packet = null;
    public void fromByteArray(byte[] payload) {
    	packet = new Packet(payload.length);
    	packet.fromByteArray(payload);
    }
    
    public void add(int type, byte [] payload)
    {
        packet = new Packet(payload.length + PacketInfo.MAX_LENGTH);
        packet.info = new PacketInfo();
        packet.info.size = payload.length;
        packet.info.type = type;
        System.arraycopy(payload, 0, packet.data, PacketInfo.MAX_LENGTH, payload.length);
    }

	public class Packet
	{
		public PacketInfo info = null;
        public byte [] data = null;

        public Packet(int size)
        {
            data = new byte[size];
        }
		
		public byte[] toByteArray()
        {
			byte [] header = info.toByteArray();
			System.arraycopy(header, 0, data, 0, header.length);
			return data;
		}
		
		public void fromByteArray(byte [] buffer)
		{
			info = new PacketInfo();
			
			byte [] header = new byte[PacketInfo.MAX_LENGTH];
			System.arraycopy(buffer, 0, header, 0, header.length);
			info.fromByteArray(header);
			
            if (info.size <= buffer.length)
            {
                data = new byte[info.size];
			    System.arraycopy(buffer, header.length, data, 0, info.size);
            }
		}
	}
	
	public class PacketInfo
	{
		public static final int MAX_LENGTH = 12;
		public static final int MAGIC = 0x20140106;
        public int magic = 0x20140106;
		public int size = 0;
		public int type = 0;
		
		
		public byte[] toByteArray()
		{
			byte [] bMagic = new byte[4];
			byte [] bSize = new byte[4];
			byte [] bType = new byte[4];
			bMagic = htonl(magic, bMagic);
			bSize = htonl(size, bSize);
			bType = htonl(type, bType);
			
			byte [] ret = new byte[bMagic.length + bSize.length + bType.length];
			System.arraycopy(bMagic, 0, ret, 0, bMagic.length);
			System.arraycopy(bSize, 0, ret, bMagic.length, bSize.length);
			System.arraycopy(bType, 0, ret, bMagic.length + bSize.length, bType.length);
			return ret;
		}
		
		public void fromByteArray(byte [] buffer)
		{
			byte [] bMagic = new byte[4];
			byte [] bSize = new byte[4];
			byte [] bType = new byte[4];
			
			System.arraycopy(buffer, 0, bMagic, 0, bMagic.length);
			System.arraycopy(buffer, bMagic.length, bSize, 0, bSize.length);
			System.arraycopy(buffer, bMagic.length + bSize.length, bType, 0, bType.length);
			
			magic = ntohl(bMagic);
			size = ntohl(bSize);
			type = ntohl(bType);			
		}
	}
	
	public static int ntohl(byte [] buf)
	{
		ByteBuffer b = ByteBuffer.wrap(buf);
		b.order(ByteOrder.BIG_ENDIAN);
		int ret = b.getInt();
		return ret;
	}
	
	public static short ntohs(byte [] buf)
	{
		ByteBuffer b = ByteBuffer.wrap(buf);
		b.order(ByteOrder.BIG_ENDIAN);
		short ret = b.getShort();
		return ret;
	}
	
	public static byte [] htonl(int val, byte [] buf)
	{
		ByteBuffer b = ByteBuffer.wrap(buf);
		b.order(ByteOrder.BIG_ENDIAN);
		b.putInt(val);
		return buf;
	}
	
	public static byte [] htons(short val, byte [] buf)
	{
		ByteBuffer b = ByteBuffer.wrap(buf);
		b.order(ByteOrder.BIG_ENDIAN);
		b.putShort(val);
		return buf;
	}
}

